#include "uart_printf.h"
#include "shell.h"
#include "stdio.h"
#include "string.h"
#include "input_event_handler.h"


#define SHELL_TASK_NAME "shell task"
#define SHELL_TASK_SIZE (32*4)  //32Byte
#define SHELL_TASK_PRI   1
TaskHandle_t shell_task_handle;

#define STREAM_BUFFER_SIZE 64
#define STREAM_BUFFER_TRIGGER_LEVEL  1
StreamBufferHandle_t shell_streamBuffer_h;

uint8_t stream_buffer[STREAM_BUFFER_SIZE] = {0};

#define CMD_PARAM_MAX  8
#define CMD_PARAM_LENTH 16

char cmd_argv[CMD_PARAM_MAX][CMD_PARAM_LENTH] = {0};

void shell_task(void *param);
uint8_t parse_cmdline(char*cmdline);
void shell_cmd_handler(int argc,char **argv);
void shell_cmd_argv_reset(void);

void shell_task_init(void)
{
	BaseType_t rval = xTaskCreate(shell_task,
						SHELL_TASK_NAME,
						SHELL_TASK_SIZE,
						NULL,
						SHELL_TASK_PRI,
						&shell_task_handle);	
	if(rval != pdPASS){
		PRINTF_LOG("shell task create fail!\r\n");
	}
	shell_streamBuffer_h = xStreamBufferCreate(STREAM_BUFFER_SIZE,STREAM_BUFFER_TRIGGER_LEVEL);
	
	if(shell_streamBuffer_h == NULL){
		PRINTF_LOG("shell stream buffer create fail!");
	}
}

void shell_task(void *param)
{
	size_t size;
	uint8_t argc = 0;
	char *argv[CMD_PARAM_MAX];

	while(1){
		size = xStreamBufferReceive(shell_streamBuffer_h,stream_buffer,STREAM_BUFFER_SIZE,portMAX_DELAY);
		if(size){
			shell_cmd_argv_reset();
			argc = parse_cmdline((char*)stream_buffer);
			for(uint8_t i=0;i<argc;i++){
				argv[i] = cmd_argv[i];
			}
			shell_cmd_handler(argc,argv);
		}
		memset(stream_buffer,0,sizeof(stream_buffer));
	}
}


BaseType_t send_cmdline_from_uartISR(void*buffer,size_t size)
{
	BaseType_t pxHigherPriorityTaskWoken = 0;
	
	xStreamBufferSendFromISR(shell_streamBuffer_h,buffer,size,&pxHigherPriorityTaskWoken);
	
	if(pxHigherPriorityTaskWoken==pdTRUE){
		
	}		
	return pxHigherPriorityTaskWoken;
}


void shell_cmd_argv_reset(void)
{
	for(uint8_t i = 0;i<CMD_PARAM_MAX;i++){
		memset(cmd_argv[i],0,CMD_PARAM_LENTH);
	}
}

uint8_t parse_cmdline(char*cmdline)
{
	uint8_t argc = 0;
	uint8_t i = 0;
	uint8_t j = 0;

	if(cmdline[0]=='\0' || cmdline[0]=='\r' ||cmdline[0] == '\n'|| cmdline[0] == ' '){
		return argc;
	}
	
	while(cmdline[i]!='\0' && cmdline[i]!='\r' && cmdline[i]!='\n'){
		if(cmdline[i] == ' '){
			argc++;
			j = 0;
		}else{
			cmd_argv[argc][j++] = cmdline[i];			
		}		
		i++;
		
	}
	
	argc++;
	
	return argc;
}

void shell_cmd_handler(int argc,char **argv)
{
	if(0 == strcmp("t",argv[0])){
		if(0 == strcmp("key",argv[1])){
			uint16_t key_evt = 0;
			if(0 == strcmp("0",argv[2])){
				key_evt = KEY_EVENT_0;
			}else if(0 == strcmp("1",argv[2])){
				key_evt = KEY_EVENT_1;
			}else if(0 == strcmp("up",argv[2])){
				key_evt = KEY_EVENT_UP;
			}
			if(key_evt){
				send_input_event(key_evt);
			}
			
		}else if(0 == strcmp("led",argv[1])){
		
		}else if(0 == strcmp("beep",argv[1])){
		
		}else if(0 == strcmp("sys",argv[1])){
		
		}else{
			printf("t key [param] ...\r\n");
			printf("        0 : send key_0 message\r\n");
			printf("        1 : send key_1 message\r\n");
			printf("        up: send key_up message\r\n");	
		}
	}else if(0 == strcmp("h",argv[0])||0 == strcmp("help",argv[0])){
		printf("t [param1] [param2] ...\r\n");
	}else{
		if(argc){
		    printf("try [help] cmd to learn\r\n");
		}
	}
	
}


